#!/bin/env python
# -*- coding:utf-8
"""
@author:xingz
@file:genetic_algorithm.py
@time:2022/05/29
"""
from __future__ import annotations

from enum import Enum
from typing import *
from random import choices, random
from heapq import nlargest
from statistics import mean

from zx_chromosome.chromosome import Chromosome

C = TypeVar('C', bound=Chromosome)


class GeneticAlgorithm(Generic[C]):
    SelectionType = Enum("SelectionType", "ROULETTE TOURNAMENT")

    def __init__(self, initial_population: List[C], threshold: float, max_generations: int = 100, mutation_chance: float = 0.01, crossover_chance: float = 0.7,
                 selection_type: SelectionType = SelectionType.TOURNAMENT) -> None:
        self._population: List[C] = initial_population
        self._threshold: float = threshold
        self._max_generations: int = max_generations
        self._mutation_chance = mutation_chance
        self._crossover_chance = crossover_chance
        self._selection_type: GeneticAlgorithm.SelectionType = selection_type
        self._fitness_key: Callable = type(self._population[0]).fitness

    def _pick_roulette(self, wheel: List[float])->Tuple[C, C]:
        return tuple(choices((self._population,)))